using System;
using System.IO;
using System.Runtime.Serialization;
using System.Xml;
using VSTalk.Engine.Core.Context;
using VSTalk.Logger;
using VSTalk.Model;

using log4net;

namespace VSTalk.Engine.Settings
{
    public class FileAccountSerializer : IAccountSerializer, IAccountDeserializer
    {
        private static readonly ILog _log = LoggerFactory.Create(typeof(FileAccountSerializer));

        private static readonly string settingFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);

        //todo: push to config
        private const string CLIENT_STORAGE_PATH = @"VSTalk\vstalk_clients.xml";

        private static readonly string filePath = Path.Combine(settingFolder, CLIENT_STORAGE_PATH);

        private Account DeserializeFile()
        {
            _log.Info("Loading user account");
            var account = new Account();
            if (!File.Exists(filePath))
            {
                return account;
            }
            var fs = new FileStream(filePath, FileMode.Open);
            try
            {
                var reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
                var ser = new DataContractSerializer(account.GetType());

                // Deserialize the data and read it from the instance.
                account = (Account)ser.ReadObject(reader, true);
                
                reader.Close();
                _log.Info("User account is loaded");
            }
            catch (Exception e)
            {
                _log.Error("Cannot deserialize contact list", e);
            }
            finally
            {
                fs.Close();
            }

            return account;
        }

        private void SerializeToFile(Account account)
        {
            _log.Info("Saving user account");
            if (!File.Exists(filePath))
            {
                File.Create(filePath).Dispose();
            }
            var writer = new FileStream(filePath, FileMode.Create);
            var ser = new DataContractSerializer(account.GetType());
            try
            {
                ser.WriteObject(writer, account);
                _log.Info("User account is saved");
            }
            catch (Exception e)
            {
                _log.Error("Cannot serialize contact list", e);
            }
            finally
            {
                writer.Close();                
            }
        }

        public void Serialize(Account account)
        {
            SerializeToFile(account);
        }

        public Account Deserialize()
        {
            return DeserializeFile();
        }
    }
}